package efu.nf.like.service.consumer;


import com.rabbitmq.client.Channel;
import efu.nf.like.common.config.RabbitConfig;
import efu.nf.like.mapper.LikeMapper;
import efu.nf.like.mapper.PostMapper;
import efu.nf.like.model.dto.LikeDTO;
import efu.nf.like.model.entity.Like;
import efu.nf.like.model.entity.Post;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.BeanUtils;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Map;

/**
 * @author lwj
 * @create 2025-10-12-23:15
 */
@Service
@Slf4j
@Transactional
@RequiredArgsConstructor
@RabbitListener(
    bindings = @QueueBinding(
        value = @Queue(value = RabbitConfig.QUEUE_NAME, durable = "true"),
        exchange = @Exchange(value = RabbitConfig.EXCHANGE_NAME),
        key = RabbitConfig.ROUTING_KEY
    )
)
public class LikeConsumer {
    private final LikeMapper likeMapper;
    private final PostMapper postMapper;

    /**
     * 接收消息
     * @param likeDTO 点赞信息
     */
    @RabbitHandler
    public void receive(LikeDTO likeDTO, Channel channel, @Headers Map<String, Object>  headers) throws IOException {
        // 签收标签
        Long tag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        try{
            // 判断点赞状态
            if(likeDTO.isUserLikeStatus()){
                // 点赞
                Like like = new Like();
                // 拷贝对象
                BeanUtils.copyProperties(likeDTO, like);
                // 添加点赞信息
                likeMapper.insert(like);
            }else{
                // 取消点赞
                likeMapper.delete(likeDTO.getUserId(),likeDTO.getPostId());
            }
            // 更新帖子点赞数
            Post post = new Post();
            // 拷贝对象
            BeanUtils.copyProperties(likeDTO, post);
            postMapper.update(post);

            // 签收消息
            channel.basicAck(tag, false);
            log.info("消息签收成功：{}", tag);
        } catch(Exception e){
            // 拒签并放回队列
            channel.basicReject(tag, true);
            log.error("消息签收失败：{}", tag);
            throw new RuntimeException(e);
        }
    }
}